#ifndef FORTUTL_H
#define FORTUTL_H

#include "fortdrv.h"

#include "common/fortconf.h"

typedef NTSTATUS (*FORT_EXPAND_STACK_FUNC)(PVOID param);

#if defined(__cplusplus)
extern "C" {
#endif

FORT_API NTSTATUS fort_driver_path(
        PDRIVER_OBJECT driver, PUNICODE_STRING regPath, PUNICODE_STRING outPath);

FORT_API DWORD fort_reg_value(PCWSTR name, DWORD defaultValue);

FORT_API PWCHAR fort_path_prefix_volume_sep(PCFORT_APP_PATH path);

FORT_API void fort_path_prefix_adjust(PUNICODE_STRING path);

FORT_API NTSTATUS fort_system32_path_init(PDRIVER_OBJECT driver, PUNICODE_STRING regPath);

FORT_API BOOL fort_svchost_path_check(PCFORT_APP_PATH path);

FORT_API NTSTATUS fort_resolve_link(PUNICODE_STRING linkPath, PUNICODE_STRING outPath);

FORT_API NTSTATUS fort_file_read(HANDLE fileHandle, ULONG poolTag, PUCHAR *outData, DWORD *outSize);
FORT_API NTSTATUS fort_file_open(PUNICODE_STRING filePath, HANDLE *outHandle);

FORT_API USHORT fort_le_u16_read(const char *cp, int offset);
FORT_API DWORD fort_le_u32_read(const char *cp, int offset);

FORT_API void fort_ascii_downcase(PUNICODE_STRING dst, PCUNICODE_STRING src);

FORT_API UINT32 fort_bits_duplicate16(UINT16 num);

FORT_API void fort_irp_set_cancel_routine(PIRP irp, PDRIVER_CANCEL routine);

FORT_API NTSTATUS fort_expand_stack(FORT_EXPAND_STACK_FUNC func, PVOID param);

FORT_API void fort_path_buffer_init(PFORT_PATH_BUFFER pb);
FORT_API BOOL fort_path_buffer_alloc(PFORT_PATH_BUFFER pb, DWORD size);
FORT_API void fort_path_buffer_free(PFORT_PATH_BUFFER pb);

FORT_API FORT_APP_PATH_DRIVE fort_path_drive_get(PCFORT_APP_PATH path);
FORT_API void fort_path_drive_adjust(PFORT_APP_PATH path, const FORT_APP_PATH_DRIVE ps_drive);

#ifdef __cplusplus
} // extern "C"
#endif

#endif // FORTUTL_H
